/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package ant.antsys;
import java.util.ArrayList;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.*;

/**
 * base class for test framework
 * @author johnson ma
 */
public abstract class TestTask extends Task implements TaskContainer {

	protected ArrayList<Task> tasks;
	protected ArrayList<TestListener> listeners = new ArrayList<TestListener>();

        /** The "if" condition to test on execution. */
        protected String ifCondition = "";
        /** The "unless" condition to test on execution. */
        protected String unlessCondition = "";

	public void init() {
		tasks = new ArrayList<Task>();
	}

	public void addTask(Task t) {
		tasks.add(t);
		//add listenser to sub test tasks
		if (t instanceof UnknownElement) {
			((UnknownElement) t).maybeConfigure();
			t = ((UnknownElement) t).getTask();
			if (t == null) {
				return;
			}
		}
		if (t instanceof TestTask) {
			TestTask testTask = (TestTask) t;
			for (TestListener listener : listeners) {
				testTask.addTestListener(listener);
			}
		}
	}

	public void addTestListener(TestListener listener) {
		listeners.add(listener);
	}

	protected void notifySuiteStart(TestSuite s) {
		for (TestListener listener : listeners) {
			listener.startTestSuite(s);
		}
	}

	protected void notifySuiteFinish(TestSuite s) {
		for (TestListener listener : listeners) {
			listener.endTestSuite(s);
		}

	}

	protected void notifyCaseStart(TestCase t) {
		for (TestListener listener : listeners) {
			listener.startTestCase(t);
		}
	}

	protected void notifyCaseFinish(TestCase t) {
		for (TestListener listener : listeners) {
			listener.endTestCase(t);
		}
	}

	protected void notifyCaseFail(TestCase t, String errorMsg, String location) {
		for (TestListener listener : listeners) {
			listener.addFailuer(t, errorMsg, location);
		}
	}

    /**
     * Sets the "if" condition to test on execution. This is the
     * name of a property to test for existence - if the property
     * is not set, the task will not execute. The property goes
     * through property substitution once before testing, so if
     * property <code>foo</code> has value <code>bar</code>, setting
     * the "if" condition to <code>${foo}_x</code> will mean that the
     * task will only execute if property <code>bar_x</code> is set.
     *
     * @param property The property condition to test on execution.
     *                 May be <code>null</code>, in which case
     *                 no "if" test is performed.
     */
    public void setIf(String property) {
        ifCondition = (property == null) ? "" : property;
    }

    /**
     * Returns the "if" property condition of this target.
     *
     * @return the "if" property condition or <code>null</code> if no
     *         "if" condition had been defined.
     */
    public String getIf() {
        return ("".equals(ifCondition) ? null : ifCondition);
    }

    /**
     * Sets the "unless" condition to test on execution. This is the
     * name of a property to test for existence - if the property
     * is set, the task will not execute. The property goes
     * through property substitution once before testing, so if
     * property <code>foo</code> has value <code>bar</code>, setting
     * the "unless" condition to <code>${foo}_x</code> will mean that the
     * task will only execute if property <code>bar_x</code> isn't set.
     *
     * @param property The property condition to test on execution.
     *                 May be <code>null</code>, in which case
     *                 no "unless" test is performed.
     */
    public void setUnless(String property) {
        unlessCondition = (property == null) ? "" : property;
    }

    /**
     * Returns the "unless" property condition of this target.
     *
     * @return the "unless" property condition or <code>null</code>
     *         if no "unless" condition had been defined.
     */
    public String getUnless() {
        return ("".equals(unlessCondition) ? null : unlessCondition);
    } 

        /**
         * check if and unless condition before run test case
         */
        protected boolean checkCondition() {
            if (!ifCondition.equals("")) {
                String ifProperty = getProject().getProperty(ifCondition);
                return ifProperty == null ? false : true;
            }

            if (!unlessCondition.equals("")) {
                String unlessProperty = getProject().getProperty(unlessCondition);
                return unlessProperty == null ? true : false;
            }
            return true;
        }

    

}

